<?php

declare(strict_types=1);
/**
 * 签到
 *
 * @contact  593809624@qq.com
 * @author   刘传望
 * @date  2025-10-15
 */

namespace App\Controller\v1;

use App\Controller\AbstractController;
use App\Service\SignInService;
use App\Service\UserService1;
use App\Exception\BusinessException;
use Hyperf\Context\Context;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Annotation\Middleware;
//token认证中间件
#[Middleware(\App\Middleware\TokenMiddleware::class)]

#[Controller(prefix: "/api/v1/signin")]
class SigninController extends AbstractController
{
    #[Inject]
    private SignInService $signInService;

    #[Inject]
    private UserService1 $userService;

    /**
     * 每日签到
     * POST /api/v1/signin/checkin
     */
    #[PostMapping("checkin")]
    public function checkin(RequestInterface $request)
    {
        try {
            $userId = (int) Context::get("login_user_id");
            
            // 执行签到
            $result = $this->signInService->signIn($userId);
            
            // 返回签到成功结果
            return $this->success([
                'signed' => true,
                'continuous_days' => $result['continuous_days'],
                'total_days' => $result['total_days'],
                'points_earned' => $result['points_earned']
            ], '签到成功');
            
        } catch (BusinessException $e) {
            // 处理业务异常（如已签到）
            return $this->fail($e->getCode(), $e->getMessage());
        } catch (\Exception $e) {
            // 处理其他异常
            return $this->fail(500, '签到失败，请稍后重试'.$e->getMessage());
        }
    }

    /**
     * 获取签到状态
     * @param $month 月份，格式: YYYY-MM，默认当前月
     * GET /api/v1/signin/status
     */
    #[GetMapping("status")]
    public function status(RequestInterface $request)
    {
        $params = $this->parseParams($request);
        try {
            $userId = (int) Context::get("login_user_id");
            
            // 获取查询参数
            $month =  isset($params['month']) ? $params['month'] : date('Y-m');
            
            // 获取连续签到天数
            $continuousDays = $this->signInService->getContinuousDays($userId);
            
            // 获取总签到天数
            $totalDays = $this->signInService->getTotalSignInDays($userId);
            
            // 获取月度签到数据
            $monthData = $this->signInService->getMonthSignInData($userId, $month);
            
            return $this->success([
                'continuous_days' => $continuousDays,
                'total_days' => $totalDays,
                'month_data' => $monthData,
                'current_month' => $month
            ]);
            
        } catch (\Exception $e) {
            return $this->fail(500, '获取签到状态失败');
        }
    }

    /**
     * 获取签到排行榜
     * @param $date 日期，格式: YYYY-MM-DD，默认今日
     * @param $limit 返回数量，默认100
     * GET /api/v1/signin/rank
     */
    #[GetMapping("rank")]
    public function rank(RequestInterface $request)
    {
        $params = $this->parseParams($request);
        try {
            // 获取查询参数

            $date =  isset($params['date']) ? $params['date'] : date('Y-m-d');

            $limit = isset($params['limit']) ? $params['limit'] : 100;
            
            // 获取排行榜数据
            $rankData = $this->signInService->getTodayRank($limit);
            
            // 格式化排行榜数据
            $rank = [];
            foreach ($rankData as $index => $userId) {
                try {
                    $userInfo = $this->userService->getUserById((string) $userId);
                    $rank[] = [
                        'rank' => $index + 1,
                        'user' => [
                            'id'=>$userInfo['id'],
                            'name'=>$userInfo['name'],
                            'avatar'=>$userInfo['avatar'],
                        ],
                        'signed_at' => $this->getSignInTime($userId, $date)
                    ];
                } catch (BusinessException $e) {}

            }
            
            return $this->success([
                'rank' => $rank,
                'date' => $date,
                'total' => count($rankData)
            ]);
            
        } catch (\Exception $e) {
            return $this->fail(500, '获取排行榜失败');
        }
    }

    /**
     * 获取用户签到时间
     */
    private function getSignInTime(int $userId, string $date): string
    {
        $signLog = DB::table('user_signin_logs')
            ->where(['user_id' => $userId,'signin_date'=>$date])
            ->first();

        return $signLog->created_at??'';
    }
}
